#include "glshapes.h"
#include "definitions.h"
#include <math.h>
#include <OpenGL/gl.h>

void wheel(float rad,float width)
{
    int i,j;
    float colorswitch = 0;
    float clr=1.0;
    glColor3f(clr, clr, clr);
    glBegin(GL_QUAD_STRIP);
    for(i=0;i<=360;i+=10){
        if(colorswitch > 4) {
            colorswitch = 0;
            clr = !clr;
            glColor3f(clr, clr, clr);
        }
        else colorswitch++;
        glNormal3f(0,sin(DEGTORAD(i)),cos(DEGTORAD(i)));
        glVertex3f(-width/2,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
        glVertex3f(width/2,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
    }
    glEnd();
    j=0;
    glColor3f(0.8, 0.8, 0.8);
    glBegin(GL_TRIANGLE_FAN);
    glNormal3f(1, 0, 0);
    glVertex3f(width/2+0.02,0,0);
    for(i=360;i>=0;i-=10){
        if(j<2) {
            j++;
            glColor3f(0,0,0);
        }
        else glColor3f(0.8,0.8,0.8);
        glNormal3f(0.707, 0.707*sin(DEGTORAD(i)), 0.707*cos(DEGTORAD(i)));
        glVertex3f(width/2,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
    }
    glEnd();
    j=0;
    glBegin(GL_TRIANGLE_FAN);
    glNormal3f(-1, 0, 0);
    glVertex3f(-(width/2+0.02),0,0);
    for(i=0;i<=360;i+=10){
        if(j<2) {
            j++;
            glColor3f(0,0,0);
        }
        else glColor3f(0.8,0.8,0.8);
        glNormal3f(-0.707, 0.707*sin(DEGTORAD(i)),0.707*cos(DEGTORAD(i)));
        glVertex3f(-width/2,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
    }
    glEnd();
}

void tube(float rad,float width)
{
        int i;

        glBegin(GL_QUAD_STRIP);
        for(i=0;i<=360;i+=20){
                glNormal3f(0, sin(DEGTORAD(i)), cos(DEGTORAD(i)));
                glVertex3f(0,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
                glVertex3f(width,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
        }
        glEnd();

        glBegin(GL_TRIANGLE_FAN);
        glNormal3f(1, 0, 0);
        glVertex3f(width,0,0);
        for(i=360;i>=0;i-=20){
                glVertex3f(width,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
        }
        glEnd();

        glBegin(GL_TRIANGLE_FAN);
        glNormal3f(-1, 0, 0);
        glVertex3f(0,0,0);
        for(i=360;i>=0;i-=20){
                glVertex3f(0,rad*sin(DEGTORAD(i)), rad*cos(DEGTORAD(i)));
        }
        glEnd();
}

void box(float length,float width,float height)
{
    int i;
    Vertex extents = {length,width,height};
    int indices[36] = {
        0,1,2,
        3,2,1,
        4,0,6,
        6,0,2,
        5,1,4,
        4,1,0,
        7,3,1,
        7,1,5,
        5,4,7,
        7,4,6,
        7,2,3,
        7,6,2};

    static Vertex vertices[8]={
        {1,1,1},
        {-1,1,1},
        {1,-1,1},
        {-1,-1,1},
        {1,1,-1},
        {-1,1,-1},
        {1,-1,-1},
        {-1,-1,-1}};

    glBegin (GL_TRIANGLES);
    for (i=0;i<36;i+=3)
    {
        Vertex v1 = mult(vertices[indices[i]],extents);
        Vertex v2 = mult(vertices[indices[i+1]],extents);
        Vertex v3 = mult(vertices[indices[i+2]],extents);
        Vertex normal = normalCross(diff(v2,v1),diff(v3,v1));//(v2-v1).cross(v3-v1);

        glNormal3f(normal.x,normal.y,normal.z);
        glVertex3f (v1.x, v1.y, v1.z);
        glVertex3f (v2.x, v2.y, v2.z);
        glVertex3f (v3.x, v3.y, v3.z);
    }
    glEnd();
}

void cylinder(float rad, float length, int res)
{
    int i;
    float py,pz;
    float ny,nz;

    glBegin(GL_QUAD_STRIP);
    for(i=0;i<=360; i+=res){
        ny = cos(DEGTORAD(i));
        nz = sin(DEGTORAD(i));
        py = rad*ny;
        pz = rad*nz;
        glNormal3f(0,ny,nz);
        glVertex3f(-length,py,pz);
        glVertex3f(length,py,pz);
    }
    glEnd();

        glBegin(GL_TRIANGLE_FAN);
        glNormal3f(-1,0,0);
    glVertex3f(-length,0,0);
    for(i=0;i<=360;i+=res){
        py = rad*cos(DEGTORAD(i));
        pz = rad*sin(DEGTORAD(i));
        glNormal3f(-1,0,0);
        glVertex3f(-length,py,pz);
    }
    glEnd();

    glBegin(GL_TRIANGLE_FAN);
        glNormal3f(1,0,0);
    glVertex3f(length,0,0);
    for(i=0;i<=360;i+=res){
        py = rad*cos(DEGTORAD(i));
        pz = rad*sin(DEGTORAD(i));
        glNormal3f(1,0,0);
        glVertex3f(length,py,pz);
    }
    glEnd();
}

void cone(float rad, float length, int res)
{
    int i;
    float px,py;
    float nx,ny;

    glBegin(GL_TRIANGLE_FAN);
    glNormal3f(0,0,1);
    glVertex3f(0,0,length/2);
    for(i=0;i<=360;i+=res){
        nx = cos(DEGTORAD(i));
        ny = sin(DEGTORAD(i));
        px = rad*nx;
        py = rad*ny;
        glNormal3f(nx,ny,0);
        glVertex3f(px,py,-length/2);
    }
    glEnd();
}

void sphere(float rad, int lats, int longs)
{
    int i, j;
    for(i = 0; i <= lats; i++) {
        float lat0 = PI * (-0.5 + (float)(i - 1) / lats);
        float z0  = rad*sin(lat0);
        float zr0 =  rad*cos(lat0);

        float lat1 = PI * (-0.5 + (float)i / lats);
        float z1 = rad*sin(lat1);
        float zr1 = rad*cos(lat1);

        glBegin(GL_QUAD_STRIP);
        for(j = 0; j <= longs; j++) {
            float lng = 2 * PI * (float)(j - 1) / longs;
            float x = cos(lng);
            float y = sin(lng);
            glNormal3f(x * zr1, y * zr1, z1);
            glVertex3f(x * zr1, y * zr1, z1);
            glNormal3f(x * zr0, y * zr0, z0);
            glVertex3f(x * zr0, y * zr0, z0);
        }
        glEnd();
    }
}
